iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 21
2
Security

看完眼眶濕濕的App開發者慘烈對抗險惡資安環境血與淚的控訴!系列 第 21

Day 21. 加密演算法要注意的那些毛 (一) - 加密模式

  • 分享至 

  • xImage
  •  

這個章節來講對稱式加密一些細節 ,如果有心細的讀者已經發現在使用 DES 及 AES ,會看到 ECB 、CBC 、PKCS7、IV 等有如外星人的語言般參數或誰誰誰說什麼比較好,這章我們就是要來掀開這些神祕面紗

加密模式(mode of operation)

分組加密演算法是按分組大小來進行加解密操作的,如DES演算法的分組是64位,而AES是128位,但實際明文的長度一般要遠大於分組大小,這樣的情況如何處理呢?

這正是即工作模式要解決的問題:明文資料流怎樣按分組大小切分,資料不對齊的情況怎麼處理等等。

早在1981年,DES演算法公佈之後,NIST在標準文獻FIPS 81中公佈了4種工作模式:

  • 電子密碼本:Electronic Code Book Mode (ECB)
  • 密碼分組連結:Cipher Block Chaining Mode (CBC)
  • 密文反饋:Cipher Feedback Mode (CFB)
  • 輸出反饋:Output Feedback Mode (OFB)

2001年又針對AES加入了新的工作模式:

  • 計數器模式:Counter Mode (CTR)

後來又陸續引入其它新的工作模式。在此僅介紹幾種常用的

ECB:電子密碼本模式

ECB模式只是將明文按分組大小切分,然後用同樣的金鑰正常加密切分好的明文分組。

image-20201005193407516

ECB的理想應用場景是短資料(如加密金鑰)的加密。此模式的問題是無法隱藏原明文資料的模式,因為同樣的明文分組加密得到的密文也是一樣的。

CBC:密碼分組連結模式

此模式是1976年由IBM所發明,引入了IV(初始化向量:Initialization Vector)的概念。IV是長度為分組大小的一組隨機,通常情況下不用保密,不過在大多數情況下,針對同一金鑰不應多次使用同一組IV。 CBC要求第一個分組的明文在加密運算前先與IV進行異或;從第二組開始,所有的明文先與前一分組加密後的密文進行異或。[區塊鏈(blockchain)的鼻祖!]

AES: 密碼分組連結模式

CBC模式相比ECB實現了更好的模式隱藏,但因為其將密文引入運算,加解密操作無法並行操作。同時引入的IV向量,還需要加、解密雙方共同知曉方可。

CFB:密文反饋模式

與CBC模式類似,但不同的地方在於,CFB模式先生成密碼流字典,然後用密碼字典與明文進行異或操作並最終生成密文。後一分組的密碼字典的生成需要前一分組的密文參與運算。

AES: 密文反饋模式

CFB模式是用分組演算法實現流演算法,明文資料不需要按分組大小對齊。

OFB:輸出反饋模式

OFB模式與CFB模式不同的地方是:生成字典的時候會採用明文參與運算,CFB採用的是密文。

AES: 輸出反饋模式

CTR:計數器模式模式

CTR模式同樣會產生流密碼字典,但同是會引入一個計數,以保證任意長時間均不會產生重複輸出。

AES: 計數器模式

CTR模式只需要實現加密演算法以生成字典,明文資料與之異或後得到密文,反之便是解密過程。CTR模式可以採用並行演算法處理以提升吞量,另外加密資料塊的訪問可以是隨機的,與前後上下文無關。

CCM:Counter with CBC-MAC

CCM模式,全稱是Counter with Cipher Block Chaining-Message Authentication Code,是CTR工作模式和CMAC認證演算法的組合體,可以同時資料加密和鑑別服務。

明文資料通過CTR模式加密成密文,然後在密文後面再附加上認證資料,所以最終的密文會比明文要長。具體的加密流程如下描述:先對明文資料認證併產生一個tag,在後續加密過程中使用此tag和IV生成校驗值U。然後用CTR模式來加密原輸入明文資料,在密文的後面附上校驗碼U。

GCM:伽羅瓦計數器模式 Galois/Counter Mode

GCM模式是CTR和GHASH的組合,GHASH操作定義為密文結果與金鑰以及訊息長度在GF(2^128)域上相乘。GCM比CCM的優勢是在於更高並行度及更好的效能。

GCM中的G就是指GMAC,C就是指CTR。
GCM可以提供對消息的加密和完整性校驗,另外,它還可以提供附加消息的完整性校驗。在實際應用場景中,有些信息是我們不需要保密,但信息的接收者需要確認它的真實性的,例如源IP,源端口,目的IP,IV,等等。因此,我們可以將這一部分作為附加消息加入到MAC值的計算當中。下圖的Ek表示用對稱秘鑰k對輸入做AES運算。最後,密文接收者會收到密文、IV(計數器CTR的初始值)、MAC值。

500px-GCM-Galois_Counter_Mode_with_IV.svg (1)

由於GCM現在屬於最嚴謹的加密模式,TLS 1.2標準使用的就是AES-GCM演算法。

加密模式優缺點

ECB

Electronic CodeBook (ECB),不變的 key,需要加密器和解密器,加解密的複雜度可能不同。

  • 優點:
    構造簡單、容易實做
  • 缺點:
    長時間下,容易被偵測。影像資料的差異性不大,很容易被辨識到重複性,相較於文字很容易受前後文的影響。

CBC

Cipher Block Chaining (CBC),不變的 key,以及前一個密文會先針對明文加密。

  • 優點:
    相同明文,會因為前一個的密文不同造就出不同的密文,也就是加密器多一個新的狀態。
  • 缺點:
    • 一個密文 Ci 的錯誤,會導致兩個明文解析錯誤 (Pi & Pi+1)。
    • 第一次加密很容易被抽換 bitwise,因為每次驅動的 Initial Vector 都相同。

CFB

Cipher FeedBack (CFB),類似 CBC,但前一個密文的結果只影響一部分的加密關係,然後將前一段密文狀態加密 key,再對明文加密。

  • 優點:
    • 支持即時 (real-time) 通訊
    • 只需要加密器,加密做兩次相當於解密。
    • 支持自同步 (self-synchronization),即使中斷連線、訊息錯誤,可以在數個週期後再次同步運作。
    • 藉由自同步的概念,可以捨棄掉 Initial Vector。
    • 後半部的明文,可以透過週期性的部分密文建立解密狀態,支持 random access。
  • 缺點:
    • error propagation 錯誤增長,當一個訊息錯誤時,需要好幾個週期後才能修正回來,這導致中間的解密訊息都不能用。
    • 雜訊過多的情況下,不宜使用。

OFB

Output FeedBack (OFB),類似於 CFB,將前一段的加密 key 拿回來加密,不依賴接收的密文狀態。

  • 優點:
    • 支持即時 (real-time) 通訊
    • 只需要加密器,加密做兩次相當於解密。
    • 相較於 CFB,沒有錯誤增長的情況。
    • 依序使用的 key,可以事先算出來,然後依次使用。
    • 雜訊下支持的能力好。
  • 缺點:
    • 必須一直保持同步
    • 訊息被修改時,不易被發現,只單純影響單一明文 (沒有錯誤增長)。
    • 起始狀態的 Initial Vector,不能重複使用,否則很容易被攻擊者抓到。
    • 加設沒有預先算 key,沒辦法解密出後半部的明文。

CTR

Counter (CTR),類似於 OFB,直接利用計數器作為加密 key。

  • 優點:
    • 加解密可以平行化處理,如果加解密速度耗時,可以選擇這一種。
    • 支持 random access。
  • 缺點:
    • 必須一直保持同步
    • 訊息被修改時,不易被發現,只單純影響單一明文 (沒有錯誤增長)。
    • 起始狀態的 Initial Vector,不能重複使用,否則很容易被攻擊者抓到。

為什麼要有初始向量 (initialization vector , IV)

有個概念我們要先知道。我們需要兩個元素去實行加密和解密:「初始向量」和「金鑰」。 你有可能會問初始向量有甚麼用途? 一般加密演算法,會將原始資料切成多個區塊進行加密動作, 如果我們只用一個金鑰值與每個明文區塊去做加密,這樣子所得到的每個密文區塊,都是相同的加密模式,會比較容易被破解。(如下圖)
截圖 2020-10-06 上午10.49.55

所以加密演算法使用一種類似遞回的方法將資料加密,它是由三個輸入去產生一個加密過的片段,分別是「上一個已加密片段」、「現在還沒加密的資料片段」、「金鑰」。 因為演算法在一開始時並沒有「上一個加密過的片段」,這就是為什麼要用到初始向量的原因了。(如下圖)
截圖 2020-10-06 上午10.50.02

加密圖片演示

用加密圖片來舉例來說明,即便不知道原理,也可以很直觀的感受,下圖為明文圖片:

羊-明文

經ECB模式加密的圖片:

羊-AES-ECB

圖中也正好驗證了AES的擴散效果:作為區域性圖案的羊頭,其紅顏色在加密後擴散到了整張圖片上。

經CBC模式有 IV 的加密的圖片:

羊-AES-CBC

初始向量 (initialization vector , IV) 需要加密嗎?

IV 與金鑰(Key)不同, 其主要目的為讓加密模式的隨機化及混淆,因此並==無安全性==考量,因此無須保密或額外加密

但由於重覆使用,容易導致泄露明文 block 的某些資訊,因此一直重用反而會導致加密模式失去安全性

不應在使用同一金鑰的情況下兩次使用同一個IV

如何產生加密圖片

注意一點==要使用 BMP 的影像格式==

使用 BMP 原因是 BMP檔案資訊不會壓縮,因為檔案很大通常不會在網路上使用這種格式

但對我們需求,不會因為加密檔案後造成無法解析圖片的問題

#產生 ECB 加密圖片
openssl enc -aes-128-ecb -e -in img.bmp -out img-ecb.bmp -K 111111
#產生 CBC 加密圖片
openssl enc -aes-128-cbc -e -in img.bmp -out img-cbc.bmp -K 111111 -iv 000000

為了程式碼簡潔,key 及 iv 只有填寫六位,長度不足,不過系統會自動補齊但會出現警告訊息

hex string is too short, padding with zero bytes to length

產生檔案後發現無法打開,這是因為二進位檔案都是透過 檔案抬頭(Header) 識別是什麼檔案,因為加密後,已經都被打散成亂數

截圖 2020-10-06 上午10.33.07

上圖左圖是正常BMP 格式,右圖是加密後檔案,顯然抬頭已不見

接著使用 HEX 編輯器,將原始檔案開頭開始的 54 bytes 抬頭資訊複製到加密後檔案,讓其圖片可以正常被解析

我使用 HEX 編輯器是 Hex Fiend

下方是我原始檔案截取出的 54 bytes 讓大家看的比較清楚,使用時需要使用自己原始的BMP Header hex 資訊

424D6057 0B000000 00003600 00002800 0000DD01 00000702 00000100 18000000 00002A57 0B00120B 0000120B 00000000 00000000 0000

截圖 2020-10-06 上午10.37.04

這樣就可以正常打開加密後的圖片

另外補充,用覆蓋開頭 54 bytes 或直接插入 54 bytes 都可以正常打開圖片

小結

上面的加密模式,裡面包含了區塊加密法串流加密法 使用的加密模式,只要確定你所需的場景,在選擇就不會出錯

但若無並行,資料缺失等考量,目前多數單純密文及範例都是使用 CBC ,雖然說越新的當然越好,但還是需要看需求考量

整理如下

特點 加密模式
區塊加密: ECB、CBC、CTR
串流加密: CFB、OFB
傳遞誤差(資料不能有缺失): CBC、CFB
不傳遞誤差(資料允許缺失): ECB、OFB、CTR
可並行: ECB、CTR
不可並行: CBC、OFB、CFB

參考資料

https://zh.wikipedia.org/wiki/%E5%88%86%E7%BB%84%E5%AF%86%E7%A0%81%E5%B7%A5%E4%BD%9C%E6%A8%A1%E5%BC%8F

https://medium.com/@JakenH/today-im-going-teach-you-how-to-encrypt-a-simple-picture-that-you-can-download-here-141ce9b0b738

https://en.wikipedia.org/wiki/Galois/Counter_Mode

https://zh.wikipedia.org/wiki/%E5%88%86%E7%BB%84%E5%AF%86%E7%A0%81

https://zh.wikipedia.org/wiki/%E6%B5%81%E5%AF%86%E7%A0%81

https://blog.csdn.net/T0mato_/article/details/53160772


上一篇
Day 20. 對稱式加密演算法 - 大家都愛用的 AES
下一篇
Day 22. 加密演算法要注意的那些毛 (二) - 填充模式
系列文
看完眼眶濕濕的App開發者慘烈對抗險惡資安環境血與淚的控訴!31
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言